<script setup lang="ts">
import {
  queryFloorData,
  queryRoomData,
  saveTemplData,
  queryTemplData,
  queryBuildData,
  queryFactoryData,
  visualqueryById
} from "@/api/visual/visualConfig";
import VisualEditer from "./visualdrag-editer/views/VisualEditer.vue";
import { PxMessage } from "px-ui";
import { flattenDataByKeys } from "@visual/utils";
import eqpTmpl from "./tmpJson";
import { ref, toRaw, watch } from "vue";
import { cloneDeep } from "@pureadmin/utils";

const selectNode = defineModel("selectNode");
const props = defineProps({
  editData: {
    type: Object || null,
    default: null
  }
});
let saveData = null;
const isMain = defineModel("isMain");
const isConfig = defineModel("isConfig");

const isTmpl = defineModel("isTmpl");

const visualData = ref(null);
const visualConfig = ref(null);
enum TemplType {
  FAC = "FAC",
  BUILD = "BUILD",
  FLOOR = "FLOOR",
  ROOM = "ROOM"
}
const facCode = localStorage.getItem("facCode");

function backMainPage() {
  isMain.value = true;
  isConfig.value = false;
  isTmpl.value = false;
  selectNode.value = {};
  visualData.value = [];
  visualConfig.value = null;
  saveData = null;
}
async function saveTempl(data) {
  let { name, code, type } = selectNode.value as any;
  let eqpId = "";
  if (type === "EQP") {
    eqpId = code;
  }
  const json = JSON.stringify(data);

  if (code) {
    //新增
    let id = "";
    if (visualConfig.value) id = visualConfig.value.id;
    saveData = await saveTemplDataFun({ id, twinsId: code, twinsName: name, type, json: json, facCode, eqpId });
    selectNode.value = {};
  } else {
    //编辑
    if (props.editData && JSON.stringify(props.editData) !== "{}") {
      let { id, twinsId, twinsName, type, facCode, eqpId, isTemplate } = props.editData as any;
      saveTemplDataFun({ id, twinsId, twinsName, type, json, facCode, eqpId, isTemplate });
    } else {
      let { id, twinsId, twinsName, type, facCode, eqpId, isTemplate } = saveData as any;
      saveTemplDataFun({ id, twinsId, twinsName, type, json, facCode, eqpId, isTemplate });
    }
  }
}
async function saveTemplDataFun({ id = "", twinsId, twinsName, eqpId, type, json, facCode, isTemplate = 0 }) {
  try {
    let tempFlag = 0;
    if (isTemplate || isTmpl.value) tempFlag = 1;
    // if ((type = "EQP")) tempFlag = 1;
    const res = await saveTemplData({ id, twinsId, twinsName, type, json, facCode, eqpId, isTemplate: tempFlag });
    PxMessage.success("保存成功");
    return res;
  } catch (error) {
    console.error(error);
    PxMessage.error("保存失败");
  }
}
async function getFloorData(param = {}) {
  const data = await queryFloorData(param);
  return data;
}
async function getRoomData(param = {}) {
  const data = await queryRoomData(param);
  return data;
}
watch(isConfig, async newVal => {
  const params: any = selectNode.value;
  if (newVal && (JSON.stringify(params) !== "{}" || props.editData)) {
    let type = params.type ? params.type : props.editData.type;

    let positionCode = "";

    if (params.code) {
      positionCode = params.code;
    } else if (props.editData?.twinsId) {
      positionCode = props.editData?.twinsId;
    } else {
      positionCode = params.code;
    }

    try {
      if (!props.editData) {
        const visualConfigRes = await queryTemplData({ twinsId: positionCode, facCode });
        visualConfig.value = visualConfigRes;
      } else {
        visualConfig.value = JSON.parse(JSON.stringify(props.editData));
      }
    } catch (error) {
      console.error(error);
    }
    try {
      let useEqpTmpl = false;
      if (visualConfig.value) {
        const { eqpId } = visualConfig.value;
        if (eqpId) positionCode = eqpId;
      } else if (type === "EQP") {
        //非编辑状态下设备，这里要设置模板
        positionCode = params.code;
        useEqpTmpl = true;
      }
      const visualDataRes = await queryVisualData(type, { positionCode: positionCode, facCode });
      visualData.value = visualDataRes;
      if (useEqpTmpl) {
        /**
         * middleTip
         *  uniqueName:eqpAttr
         * ListIndex
         *  uniqueName:eqpStat
         * VChartLine
         *  uniqueName:eqpAttr
         * TableAlert
         *  uniqueName:eqpId
         * DepFilter
         * "uniqueName": "eqpInfo"
         *
         */
        const tmplSource = flattenDataByKeys(visualDataRes, "uniqueName");
        let eqpTmplCopy = cloneDeep(eqpTmpl);
        const { imgName } = selectNode.value as any;
        eqpTmplCopy.forEach(item => {
          const { dataBinding, component } = item;
          if (component === "VImage") {
            if (imgName) {
              item.propValue.name = imgName;
            }
          } else if (component === "DepFilter") {
            const eqpInfo = tmplSource["eqpInfo"];
            if (eqpInfo) {
              const { children } = eqpInfo;
              if (children && children[0]) {
                const { className } = children[0];
                const maps = {
                  ELECTRICTITY: "depelector", //电科
                  GAS: "depair", //气化科
                  MACHINE: "depmech", //机械科
                  WATER: "depwater" //水科
                };
                if (className) {
                  item.propValue.activeName = maps[className];
                  item.propValue.excludes = getValuesExceptKey(maps, className);
                } else {
                  item.delete = true;
                }
              } else {
                item.delete = true;
              }
            } else {
              item.delete = true;
            }
          } else if (dataBinding && JSON.stringify(dataBinding) !== "{}") {
            const { type } = dataBinding;
            let tmplKey = type;
            if (type.indexOf("ALARM") !== -1) {
              tmplKey = `ALARM${positionCode}`;
              dataBinding.type = tmplKey;
            }
            if (tmplSource[tmplKey]) {
              dataBinding.val = tmplSource[tmplKey];
            } else {
              item.dataBinding = {};
            }
          }
        });
        eqpTmplCopy = filterOutTrueValues(eqpTmplCopy, "delete");
        visualConfig.value = { json: JSON.stringify(eqpTmplCopy) };
      }
    } catch (error) {
      console.error(error);
    }
  } else {
    visualData.value = [];
  }
});
function queryVisualData(type, data) {
  const { facCode } = data;
  /**
   * FAC--厂区
   * BUILD--楼栋
   * FLOOR--楼层
   * ROOM--房间
   */
  if (type === "FAC" && facCode) {
    // const formData = new FormData();
    // formData.append("facCode", facCode);
    let classList = JSON.parse(localStorage.getItem("classList"));
    classList = pluck(classList, "code");
    return queryFactoryData({ ...data, classList });
  } else if (type === "BUILD") {
    return queryBuildData(data);
  } else if (type === "FLOOR") {
    return getFloorData(data);
  } else if (type === "ROOM" || type === "AREA") {
    //这里不确定是不是应该使用同一个接口
    return getRoomData(data);
  } else if (type === "EQP") {
    return visualqueryById({ eqpId: data.positionCode });
  }
  throw new Error("未匹配到type值");
}
function getValuesExceptKey(obj, key) {
  // 获取对象的所有键
  const keys = Object.keys(obj);
  // 使用filter方法排除指定的键，并映射到值
  const values = keys.filter(k => k !== key).map(k => obj[k]);
  return values;
}
function filterOutTrueValues(array, key) {
  // 使用filter方法遍历数组，如果对象的指定键不等于true，则保留该对象
  return array.filter(item => !(item.hasOwnProperty(key) && item[key]));
}
/**
 * 根据指定键从对象数组中提取对应值，发生任何错误时返回空数组。
 * @param {any} arr - 要处理的数组
 * @param {string} key - 要提取的键
 * @returns {Array} 提取出的值数组，出错时返回 []
 */
function pluck(arr, key) {
  try {
    // 不是数组或 key 不是字符串，直接返回空数组
    if (!Array.isArray(arr) || typeof key !== "string") {
      return [];
    }
    // 使用 reduce 一次遍历完成提取并过滤不存在的键
    return arr.reduce((result, item) => {
      if (item != null && typeof item === "object" && key in item) {
        result.push(item[key]);
      }
      return result;
    }, []);
  } catch (e) {
    // 捕获任何运行时错误，保证稳健性
    return [];
  }
}
</script>

<template>
  <div v-show="!isMain && isConfig" class="add-config-detail">
    <VisualEditer
      v-if="!isMain && isConfig"
      :visualData="visualData"
      :visualConfig="visualConfig"
      @backMainPage="backMainPage"
      @saveTemplData="saveTempl"
    />
  </div>
</template>

<style lang="scss" scoped>
.add-config-content {
  background-color: white;

  // :deep(.px-collapse) {
  //   margin: 24px;
  //   border-radius: 4px;
  // }

  // :deep(.px-collapse-item__header) {
  //   min-height: 40px;
  //   padding: 14px 15px 7px !important;
  //   font-size: 16px;
  //   background: #e7eefb;
  //   border-radius: 4px;

  //   &.is-active {
  //     border-radius: 4px 4px 0 0;
  //   }
  // }

  // :deep(.px-collapse-item__arrow) {
  //   margin-left: 5px;
  //   transform: rotate(-90deg);

  //   &.is-active {
  //     transform: rotate(90deg);
  //   }
  // }

  .collapse-content {
    padding: 24px;
  }
  // ::v-deep .px-collapse-item__content {

  // }
  // :deep(.px-collapse-item__wrap) {
  //   border: 1px solid rgb(223 223 223);
  //   border-top: 0;
  //   border-radius: 0 0 4px 4px;
  // }

  .px-dialog-footer {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 50px;
    padding-top: 10px;
    padding-right: 34px;
    text-align: right;
    background: white;
    box-shadow: 0 0 10px 0 rgb(0 0 0 / 16%);
  }
}
</style>
